﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using EPiServer.Cms.Shell.UI.Rest.ContentQuery;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using EPiServer.Shell.ObjectEditing;
using System.Linq;
using StructureMap;
using StructureMap.Configuration.DSL;

namespace OpenWaves.EPiServer.GenericListProperty
{
    [InitializableModule]
    [ModuleDependency(typeof(ServiceContainerInitialization))]
    public class TypesBootstrapper : IConfigurableModule
    {
        public void ConfigureContainer(ServiceConfigurationContext context)
        {
            context.Container.EjectAllInstancesOf<ContentSoftLinkIndexer>();
            context.Container.Configure(c => c.For<ContentSoftLinkIndexer>().Use<CustomContentSoftLinkIndexer>());
        }

        private IEnumerable<Type> GetModelTypes()
        {
            var types = AppDomain.CurrentDomain.GetAssemblies()
                                 .SelectMany(a =>
                                             a.GetTypes().Where(
                                                 x =>
                                                 Attribute.IsDefined(x, typeof(ContentTypeAttribute))));

            return types;
        }

        public void Initialize(InitializationEngine context)
        {
            var serviceLocator = global::EPiServer.ServiceLocation.ServiceLocator.Current;

            var propertyDefinitionTypeRepository = serviceLocator.GetInstance<IPropertyDefinitionTypeRepository>();


            var blockTypes = this.GetModelTypes().Where(t => typeof(BlockData).IsAssignableFrom(t));
            foreach (var blockType in blockTypes)
            {
                var isGenericListItemBlock =
                    blockType.GetCustomAttributes(false).OfType<GenericListBlockItemAttribute>().Any();
                if (!isGenericListItemBlock)
                {
                    continue;
                }

                var propertyType = typeof(GenericListPropertyBackingType<>).MakeGenericType(blockType);

                var propertyDefinitionType = propertyDefinitionTypeRepository.Load(propertyType);
                if (propertyDefinitionType == null)
                {
                    propertyDefinitionType = new PropertyDefinitionType
                    {

                        DataType = PropertyDataType.LongString,
                        AssemblyName = propertyType.Assembly.FullName,
                        TypeName = propertyType.FullName,
                        Name = "List of " + blockType.Name
                    };

                    propertyDefinitionTypeRepository.Save(propertyDefinitionType);
                }

                var enumerableOfBackingType = typeof(IEnumerable<>).MakeGenericType(blockType);

                serviceLocator.GetInstance<MetadataHandlerRegistry>()
                              .RegisterMetadataHandler(enumerableOfBackingType,
                                                       new PropertyListEditorDescriptor(),
                                                       PropertyListEditorDescriptor.UIHint);
            }

            /*
               [Display(Name = "Items list - default", Order = 1023)]
        [BackingType(typeof(EditorialBlockBackingType))]
        public virtual IEnumerable<EditorialBlock> ItemsList { get; set; }
             */

            /*
    [EditorHint(PropertyListEditorDescriptor.UIHint)]
    [PropertyDefinitionTypePlugIn(Description = "EditralBlock - Generic List")]
    public class EditorialBlockBackingType: ListPropertyBackingType<EditorialBlock>
    {
        protected override ListPropertyBackingType<EditorialBlock> CreateListInstance()
        {
            return new EditorialBlockBackingType();
        }
    }

    [EditorHint(PropertyListEditorDescriptor.UIHint)]
    [PropertyDefinitionTypePlugIn(Description = "ImageBlock - Generic List")]
    public class ImageBlockBackingType : ListPropertyBackingType<ImageBlock>
    {
        protected override ListPropertyBackingType<ImageBlock> CreateListInstance()
        {
            return new ImageBlockBackingType();
        }
    }
     */

            /*
            EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<MetadataHandlerRegistry>().RegisterMetadataHandler(typeof(IEnumerable<EditorialBlock>),
                new PropertyListEditorDescriptor(), PropertyListEditorDescriptor.UIHint);
            EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<MetadataHandlerRegistry>().RegisterMetadataHandler(typeof(IEnumerable<ImageBlock>),
               new PropertyListEditorDescriptor(), PropertyListEditorDescriptor.UIHint);
             */
        }

        public void Uninitialize(InitializationEngine context)
        {
            throw new NotImplementedException();
        }

        public void Preload(string[] parameters)
        {
            throw new NotImplementedException();
        }
    }
}